<?php

namespace IDock\Insurance\ZYIC\Request;

use Exception;
use IDock\Insurance\ZYIC\ZYICEnums;
use IDock\Insurance\ZYIC\Request\AllZYICRequest;
use IDock\Insurance\ZYIC\Response\PremiumInquiryResponse;
use IDock\Printer\NonCar\NonCarSubCoveragePrinter;
use IDock\Visitor\NonCar\NonCarProductVisitor;
use IDock\Visitor\Premium\PremiumChargingPileVisitor;
use IDock\Visitor\Premium\PremiumCoverageVisitor;
use IDock\Visitor\Premium\PremiumInquiryVisitor;
use IDock\Visitor\Premium\PremiumRelationVisitor;

class PremiumInquiryRequest extends AllZYICRequest
{
    public $route = 'channelInterface/V04';

    protected $response = PremiumInquiryResponse::class;

    protected $urlTip = '报价接口';

    /*** @var  PremiumInquiryVisitor $visitor */
    protected $visitor;

    public $systemFlag = '';

    public $planName = '';

    public function generate(): array
    {
        $this->planName = $this->visitor->getExtInfoVisitor()->argc['planName'] ?? '';
        $data = [
            'isRalationBI' => $this->visitor->biStartData ? '1' : '0',
            'isRalationCI' => $this->visitor->ciStartData ? '1' : '0',
            'prpTmain' => [
                'planName' => $this->planName,
                'systemFlag' => $this->systemFlag,
            ],
            'prpTinsureds' => $this->getRelationData(),
            'prpTitemCar' => $this->carData(),
            'prpTinvoiceInfo' => [
                'invoiceType' => '5', //暂不开票
            ],
        ];
        if($this->visitor->biStartData){
            $data['bi'] = $this->getBiData();
        }
        if($this->visitor->ciStartData){
            $data['ci'] = $this->getCiData();
        }
        //充电桩
        if($this->visitor->getChargingPileVisitorList()){
            $data['prpTnewEnergys'] = $this->getChargingList();
        }
        //非车
        if($this->visitor->getNonCarInquiryVisitor()->getNonCarList()){
            $data['nonCar'] = $this->getNonCarList();
            $data['insuranceNonCar'] = '1';//非车必填字段
        }
        return $data;
    }

    public function getNonCarList()
    {
        /**
         * @var NonCarProductVisitor $single
         */
        $single = $this->visitor->getNonCarInquiryVisitor()->getNonCarList()[0] ?? [];
        return [
            'nonCarType' => 2,//2 代表乐驾保，3代表驾意险
            'insurancePlan' => $single->planCode,//非车产品计划号
            'plan' => $this->visitor->getVehicleVisitor()->vehicleSeat,
            'gasAddress' => $this->visitor->getInsuredVisitor()->address,
        ];
    }

    private function getChargingList()
    {
        $list = [];
        $no = 1;
        foreach ($this->visitor->getChargingPileVisitorList() as $visitor){
            /*** @var  $visitor PremiumChargingPileVisitor */
            $list[] = [
                'serialNo' => (string)$no,
                'chargingPostType' => $visitor->chargingPileType,
                'chargingPostCode' => $visitor->chargingPileCode,
                'chargingPostYearLimit' => ZYICEnums::$chargingPileYearLimit[$visitor->chargingPileYearLimit],
                'chargingPostKind' => ZYICEnums::$chargingPileKind[$visitor->chargingPileKind],
                'chargingPostAddressType' => ZYICEnums::$chargingPileAddressType[$visitor->chargingPileAddressType],
                'chargingPostAddress' => $visitor->chargingPileAddress,
                'lossSumLimit' => $visitor->lossAmount,
                'liabilitySumLimit' => $visitor->liabilityAmount,
            ];
            $no += 1;
        }
        return $list;
    }

    private function getRelationData(): array
    {
        $owner = $this->visitor->getOwnerVisitor();
        $ownerData = $this->customerModel($owner);
        $ownerData['insuredFlag'] = '5';
        $apply = $this->visitor->getApplicantVisitor();
        $applyData = $this->customerModel($apply);
        $applyData['insuredFlag'] = '2';
        $applyData['insuredSource'] = '5';
        $insured = $this->visitor->getInsuredVisitor();
        $insuredData = $this->customerModel($insured);
        $insuredData['insuredFlag'] = '1';
        return [
            $ownerData,
            $applyData,
            $insuredData,
        ];
    }

    private function customerModel(PremiumRelationVisitor $model)
    {
        $arr = [
            'insuredType' => $model->typeCode == 'R1' ? '1' : '2',
            'insuredName' => $model->name,
            'identifyType' => ZYICEnums::$certificateTypeCode[$model->certificateTypeCode] ?? '',
            'identifyNumber' => $model->certificateNo,
            'postAddress' => $model->address,
            'identityValidStartDate' => $model->certificateStartDate ,
            'identityValidEndDate' => $model->certificateEndDate ,
            'nationality' => 'CHN',
            //'customerSource' => '05',
            'customerSource' => $this->visitor->getExtInfoVisitor()->argc['customerSource'] ?? '05',//客户来源 默认 市场国内
            'mobile' => $model->mobile
        ];
        if ($arr['insuredType'] == '1') {
            //个人
            $arr['occupationCode'] =  '800';
            $arr['occupationGrade'] = '008';//职业大类
            $arr['birthday'] = $this->getBirthday($model->certificateNo);
            $arr['sex'] = $this->getGenderByIDcard($model->certificateNo);
//            $arr['age'] = '18';

            $arr['email'] = $model->email;
            $arr['insuredSource'] = '';
        }else{
            $arr['businessSourceName'] = 'O82';
        }
        return $arr;
    }

    private function getBirthday($idCard)
    {
        if (strlen($idCard) != 18) {
            throw new Exception("身份证位数不合法");
        }
        return substr($idCard, 6, 4) . '-' . substr($idCard, 10, 2) . '-' . substr($idCard, 12, 2);
    }

    /**
     * 主信息
     * @return array
     */
    private function getBiData(): array
    {
        $data = [
            'riskCode' => $this->visitor->getVehicleVisitor()->isNewEnergy ? 'DEG' : 'DEB',
            'immeValidFlag' => intval($this->visitor->biEffectFlag),
            'startDate' => $this->visitor->biStartData ? date('Y-m-d',strtotime($this->visitor->biStartData)) : '',
            'startHour' => $this->visitor->biStartData ? '00' : '',
            'endDate' => $this->visitor->biEndData ? date('Y-m-d',strtotime($this->visitor->biEndData)) : '',
            'endHour' => $this->visitor->biStartData ? '24' : '',
//            'checkCode' => $this->visitor->getExtInfoVisitor()->argc['checkCode'] ?? '',
//            'checkCodeAnswer' => $this->visitor->getExtInfoVisitor()->argc['checkCodeAnswer'] ?? '',
            'prpTitemKinds' => $this->getCoverageList(),
            'planName' => $this->planName,
            'proposalNo' => $this->visitor->getExtInfoVisitor()->argc['proposalNoBI'] ?? ''
        ];
        if($this->visitor->biStartData){
            $data['startHour'] = date('H',strtotime($this->visitor->biStartData));
        }
        return $data;
    }

    private function getCiData()
    {
        $data = [
            'riskCode' => 'DDA',
            'immeValidFlag' => intval($this->visitor->ciEffectFlag),
            'startDate' => $this->visitor->ciStartData ? date('Y-m-d',strtotime($this->visitor->ciStartData)) : '',
            'startHour' => $this->visitor->ciEndData ? '00' : '',
            'endDate' => $this->visitor->ciEndData ? date('Y-m-d',strtotime($this->visitor->ciEndData)) : '',
            'endHour' => $this->visitor->ciEndData ? '24' : '',
            'planName' => $this->planName,
            'proposalNo' => $this->visitor->getExtInfoVisitor()->argc['proposalNoCI'] ?? ''
        ];
        if($this->visitor->ciStartData){
            $data['startHour'] = date('H',strtotime($this->visitor->ciStartData));
        }
        if($this->visitor->ciEffectFlag){
            $data['startMinute'] = date('i',strtotime($this->visitor->ciStartData));
            $data['endMinute'] = date('i',strtotime($this->visitor->ciEndData));
        }
        return $data;
    }

    /**
     * 车辆信息
     * @return array
     */
    private function carData(): array
    {
        $data = [
            'otherNature7' => $this->visitor->getVehicleVisitor()->isNewVehicle ? '0' : '1',//是否已上牌，1 是；0 否
            'otherNature8' => intval($this->visitor->getVehicleVisitor()->nonlocalCar) ,//是否外地车
            'licenseNo' => $this->visitor->getVehicleVisitor()->licenseNo,
            'engineNo' => $this->visitor->getVehicleVisitor()->engineNo,
            'vinNo' => $this->visitor->getVehicleVisitor()->vin,
            'carKindCode' => ZYICEnums::$carKindCode[$this->visitor->getVehicleVisitor()->carKindCode] ?? '',//车辆种类
            'carkindClass' => $this->getCarClass(),
            'useNatureCode' => ZYICEnums::$causeType[$this->visitor->getVehicleVisitor()->causeType] ?? '',
            'enrollDate' => $this->visitor->getVehicleVisitor()->firstRegisterDate,
            'vehicleStyle' => $this->visitor->getVehicleVisitor()->vehicleStyleCode,
            'licenseKindCode' => $this->visitor->getVehicleVisitor()->licenseTypeCode,
            'newVehicleFlag' =>intval($this->visitor->getVehicleVisitor()->isNewVehicle) ,
            'chgOwnerFlag' =>intval($this->visitor->getVehicleVisitor()->isTransfer or $this->visitor->getVehicleVisitor()->isCiTransfer),
            'loanVehicleFlag' =>  0,
            'vehicleCode' =>  $this->visitor->getVehicleVisitor()->vehicleModelCode,
            'fuelType' =>  ZYICEnums::$energyType[$this->visitor->getVehicleVisitor()->energyTypeCode] ?? '',
            'carCheckStatus' =>  ZYICEnums::$carCheckCode[$this->visitor->getExtInfoVisitor()->carCheckCode] ?? '',//验车情况
            'certificateDate' => $this->visitor->getVehicleVisitor()->issueDate,
            'seatCount' => $this->visitor->getVehicleVisitor()->vehicleSeat,
            'tonCount' => round($this->visitor->getVehicleVisitor()->vehicleTonnage,2) / 1000,
            'wholeWeight' => $this->visitor->getVehicleVisitor()->wholeWeight,
            'actualValue' => $this->visitor->getVehicleVisitor()->actualValue,
            'fairValue' => $this->visitor->getVehicleVisitor()->actualValue,
            'carValueType' => '1',//1实际价值；2公允价值
            'carInsuredRelation' => '0',//0 所有人
            'vehicleOwnerNature' => $this->visitor->getOwnerVisitor()->typeCode == 'R1' ? '1' : '3',
        ];
        if (empty($data['carKindCode'])) {
            throw new \Exception("不支持该车辆种类");
        }
        if (empty($data['useNatureCode'])) {
            throw new \Exception("不支持该车辆使用性质");
        }
        if (empty($data['carCheckStatus'])) {
            throw new \Exception("不支持该验车情况");
        }
        if ($this->visitor->getVehicleVisitor()->isTransfer or $this->visitor->getVehicleVisitor()->isCiTransfer) {
            $data['transferDate'] = $this->visitor->getVehicleVisitor()->transferDate;
        }
        if($data['carCheckStatus'] == '1'){
            $data['carChecker'] = $this->visitor->getExtInfoVisitor()->carChecker;
            $data['carCheckTime'] = date('Y-m-d H:m',strtotime($this->visitor->getExtInfoVisitor()->carCheckDate));
        }
        return $data;
    }

    private function getCarClass()
    {
        $carType = $this->visitor->getVehicleVisitor()->carKindCode;
        $seat = $this->visitor->getVehicleVisitor()->vehicleSeat;
        $tong = round($this->visitor->getVehicleVisitor()->vehicleTonnage,2) / 1000;
        if($carType == '100'){
            //客车
            if($seat < 6){
                $code = '345002001';
            }elseif($seat < '10'){
                $code = '345002002';
            }else{
                $code = '345002003';
            }
        }else{
            //货车
            if($tong < '2'){
                $code = '345002008';
            }elseif($tong < '5'){
                $code = '345002009';
            }elseif($tong < '10'){
                $code = '345002010';
            }else{
                $code = '345002011';
            }
        }
        return $code;
    }

    /**
     * 险种信息
     * @return array
     */
    private function getCoverageList(): array
    {
        $list = [];
        $no = 1;

        $coverageList = $this->visitor->getCoverageVisitorList();
        $coverageList = array_combine(array_column($coverageList, 'coverageCode'), $coverageList);

        foreach ($coverageList as $coverage) {

            /*** @var PremiumCoverageVisitor $coverage */

            //交强险去除
            if ($coverage->coverageCode == 'C01001') {
                continue;
            }
            $one = [
                'itemKindNo' => (string)$no,
                'kindCode' => ZYICEnums::$coverageCode[$coverage->coverageCode],
                'amount' => $coverage->amount,
                'itemKind_Flag5' => '0',
            ];
            //车损险
            if(in_array($coverage->coverageCode,['C02001','C12001'])){
                $one['amount'] = $this->visitor->getVehicleVisitor()->actualValue;
            }
            //乘客险主险
            if (in_array($coverage->coverageCode, ['C05001', 'C15001'])) {
                $one['quantity'] = strval($this->visitor->getVehicleVisitor()->vehicleSeat - 1);
                $one['unitAmount'] = $coverage->unitAmount;
            }
            //乘客险附加险
            if (in_array($coverage->coverageCode, ['C05002', 'C05003', 'C15002', 'C15003'])) {
                $one['quantity'] = strval($this->visitor->getVehicleVisitor()->vehicleSeat - 1);
                $one['unitAmount'] = $coverage->amount;
                $one['amount'] = (string)floatval($one['quantity'] * $coverage->amount);
            }
            //修理期间天数
            if(in_array($coverage->coverageCode, ['C02003', 'C12003'])){
                $one['quantity'] = intval($coverage->quantity);
                $one['unitAmount'] = $coverage->unitAmount;
            }
            //发动机进水损坏除外特约
            if(in_array($coverage->coverageCode, ['C02005', 'C12005'])){
                $one['zoneCode'] = '0';
            }
            //绝对免赔率
            if (in_array($coverage->coverageCode, ['C02006', 'C03005', 'C04004','C05004','C12006', 'C13005', 'C14004', 'C15004'])) {
                $one['deductibleRate'] = $coverage->deductionRate;
            }
            //特约
            if(in_array($coverage->coverageCode,['C08001','C08002','C08003','C08004','C18001','C18002','C18003','C18004'])){
                $one['quantity'] = $coverage->serviceTimes;
            }
            //精神伤害抚慰金
            if (in_array($coverage->coverageCode, [ 'C03003', 'C04002', 'C05002', 'C13003','C14002','C15002'])) {
//                $one['unitAmount'] = $coverage->amount;
            }
            if($coverage->coverageCode == 'C16001'){
                //附加电网保额
                $one['amount'] = $this->visitor->getVehicleVisitor()->actualValue;
            }
            //司机险
            if (in_array($coverage->coverageCode, ['C04001', 'C04002', 'C04003', 'C14001', 'C14002', 'C14003'])) {
                $one['quantity'] = 1;
                $one['unitAmount'] = $coverage->unitAmount ?: $coverage->amount;
            }

            $no += 1;

            $list[] = $one;
        }

        return $list;
    }

    /**
     * 通过身份证获取性别
     * @param $idcard
     * @return int
     * @throws \Exception
     */
    private function getGenderByIDcard($idCard)
    {
        if (strlen($idCard) != 18) {
            throw new \Exception("身份证位数不合法");
        }
        $gender = intval(substr($idCard, 16, 1)) % 2;
        return $gender ? '1' : '2';
    }
}
